﻿#pragma once

#include "precomp.h"
#include "global_state.h"
#include <irrKlang.h>

#pragma comment(lib, "irrKlang.lib")

// Интерфейс для irrKlang'а
class CL_ReadFile : public irrklang::IFileReader
{
public:

	// constructor, store size of file and filename
	CL_ReadFile(CL_IODevice openedFile, const char* filename)
	{
		File = openedFile;
		strcpy(Filename, filename);
	}

	~CL_ReadFile()
	{
	}

	//! reads data, returns how much was read
	irrklang::ik_s32 read(void* buffer, unsigned int sizeToRead)
	{
		return (irrklang::ik_s32)File.read(buffer, sizeToRead);
	}

	//! changes position in file, returns true if successful
	bool seek(irrklang::ik_s32 finalPos, bool relativeMovement)
	{
		return File.seek(finalPos, relativeMovement ? CL_IODevice::seek_cur : CL_IODevice::seek_set);
	}

	//! returns size of file
	irrklang::ik_s32 getSize()
	{
		return File.get_size();
	}

	//! returns where in the file we are.
	irrklang::ik_s32 getPos()
	{
		return File.get_position();
	}

	//! returns name of file
	const irrklang::ik_c8* getFileName()
	{
		return Filename;
	}

   CL_IODevice File;
   char Filename[1024];
   irrklang::ik_s32 FileSize;
};

class CL_FileFactory : public irrklang::IFileFactory
{
public:

	CL_FileFactory(CL_VirtualDirectory dir)
	{
		res_dir = dir;
	}
	~CL_FileFactory()
	{
	}
	
   //! Opens a file for read access. Simply return 0 if file not found.
	virtual irrklang::IFileReader* createFileReader(const char* filename)
   {

	   CL_IODevice file = res_dir.open_file_read(filename);

	   if (file.is_null())
         return 0;

      return new CL_ReadFile(file, filename);
   }
private:
	CL_VirtualDirectory res_dir;
};


class _SoundManager{
public:
	_SoundManager();
	~_SoundManager();
	void Load(CL_ResourceManager &resources, CL_ResourceManager &m_resources);
	void PlaySound(CL_String sname);
	void PlaySound_VolumeControl(CL_String sname, float vol);
	void PlayMusic(CL_String sname);
	void StopMusic();
	int GetMusicPosition();
	void UpdateMusicVolume();
	void MusicPlayer();
private:
	irrklang::ISoundEngine* engine;
	irrklang::ISoundEngine* mengine;
	std::map<std::string, int> sizes;
	std::map<std::string, char*> buffers;
	std::map<std::string, irrklang::ISoundSource*> sounds;
	std::map<std::string, float> volumes;
	std::map<std::string, irrklang::ISoundSource*> tracks;
	CL_VirtualDirectory music_dir;
	irrklang::ISoundSource* current_track;
	irrklang::ISound* current_music;

	unsigned int sound_delay;
	std::map<std::string, unsigned int> delays;

	int initialized;
	CL_Thread music_thread;
	CL_Mutex music_mutex;
	CL_Mutex stop_music_mutex;
	int to_play;
	int to_stop;
	int close_player;
	CL_String track_to_play;
};

extern _SoundManager smanager;
